from django.shortcuts import render
from django.http import HttpRequest, HttpResponse
from django.views.generic import View
from rest_framework.views import APIView
from rest_framework.decorators import api_view
from rest_framework.request import Request
from utils.common_tools import generate_signature, get_client_ip
from utils.jsonResponse import SuccessResponse, ErrorResponse, DetailResponse
from apps.generate_secret.models import AppSecret
# from apps.generate_secret.tools import generate_signature
from django.db.models import Q
import logging
from django.core.cache import cache
import json
import traceback
from datetime import datetime

log = logging.getLogger('log')


# Create your views here.



class AppSecretViews(APIView):
    """
    应用秘钥管理API
    """
    
    def post(self, request: Request):
        """
        生成应用签名token
        POST /api/generate_secret/app/secret/create
        请求体: {
            "app_id": "my-app-001",
            "senderNonce": "sender_nonce_value",
            "recipNonce": "recip_nonce_value", 
            "messageTime": "20250101000000"
        }
        """
        client_ip = get_client_ip(request)
        request_id = f"req_{datetime.now().strftime('%Y%m%d%H%M%S%f')[:-3]}"
        
        log.info(f"[{request_id}] 开始处理生成应用签名请求 - IP: {client_ip}, 路径: {request.path}")
        log.info(f"[{request_id}] 请求头信息: {dict(request.headers)}")
        
        try:
            # 记录请求体
            request_body = request.body.decode('utf-8') if request.body else '{}'
            log.info(f"[{request_id}] 请求体: {request_body}")
            
            data = json.loads(request.body) if request.body else {}
            app_id = data.get('appId')
            sender_nonce = data.get('senderNonce')
            recip_nonce = data.get('recipNonce')
            message_time = data.get('messageTime')
            
            log.info(f"[{request_id}] 解析参数 - appId: {app_id}, senderNonce: {sender_nonce}, recipNonce: {recip_nonce}, messageTime: {message_time}")
            
            # 验证必需参数
            if not app_id:
                log.warning(f"[{request_id}] 参数验证失败: appId参数不能为空")
                return ErrorResponse(data="appId参数不能为空")
            if not sender_nonce:
                log.warning(f"[{request_id}] 参数验证失败: senderNonce参数不能为空")
                return ErrorResponse(data="senderNonce参数不能为空")
            # if not recip_nonce:
            #     log.warning(f"[{request_id}] 参数验证失败: recipNonce参数不能为空")
            #     return ErrorResponse(data="recipNonce参数不能为空")
            if not message_time:
                log.warning(f"[{request_id}] 参数验证失败: messageTime参数不能为空")
                return ErrorResponse(data="messageTime参数不能为空")
            
            log.info(f"[{request_id}] 参数验证通过，开始查询应用信息")
            
            # 通过app_id获取app_secret
            app_secret_obj = AppSecret.objects.filter(
                app_id=app_id,
                is_delete=False,
                status=True
            ).first()
            
            if not app_secret_obj:
                log.warning(f"[{request_id}] 应用不存在或已被禁用 - app_id: {app_id}")
                return ErrorResponse(data="应用不存在或已被禁用")
            
            log.info(f"[{request_id}] 应用信息查询成功 - app_id: {app_id}, 应用状态: {app_secret_obj.status}")
            
            # 构建签名参数
            signature_params = {
                "app_id": app_id,
                "senderNonce": sender_nonce,
                # "recipNonce": recip_nonce,
                "messageTime": message_time
            }
            
            log.info(f"[{request_id}] 开始生成签名token - 参数: {signature_params}")
            
            # 使用tools.py中的generate_signature生成token
            token = generate_signature(signature_params, app_secret_obj.app_secret)
            
            result = {
                "app_id": app_id,
                "app_token": token,
                "message": "应用签名生成成功"
            }
            
            log.info(f"[{request_id}] 签名生成成功 - app_id: {app_id}, token长度: {len(token)}")
            
            return DetailResponse(data=result, msg="应用签名生成成功")
            
        except json.JSONDecodeError as e:
            log.error(f"[{request_id}] JSON解析失败: {str(e)}, 请求体: {request_body}")
            return ErrorResponse(data="请求体格式错误，请使用JSON格式")
        except Exception as e:
            log.error(f"[{request_id}] 生成应用签名失败: {str(e)}")
            log.error(f"[{request_id}] 异常堆栈: {traceback.format_exc()}")
            return ErrorResponse(data=f"生成应用签名失败: {str(e)}")
    
    def get(self, request: Request):
        """
        获取应用秘钥
        GET /api/generate_secret/app/secret/get?app_id=xxx
        """
        client_ip = self._get_client_ip(request)
        request_id = f"req_{datetime.now().strftime('%Y%m%d%H%M%S%f')[:-3]}"
        
        log.info(f"[{request_id}] 开始处理获取应用秘钥请求 - IP: {client_ip}, 路径: {request.path}")
        log.info(f"[{request_id}] 查询参数: {dict(request.GET)}")
        
        try:
            app_id = request.GET.get('app_id')
            
            if not app_id:
                log.warning(f"[{request_id}] 参数验证失败: app_id参数不能为空")
                return ErrorResponse(data="app_id参数不能为空")
            
            log.info(f"[{request_id}] 开始查询应用信息 - app_id: {app_id}")
            
            app_secret_obj = AppSecret.objects.filter(
                app_id=app_id,
                is_delete=False
            ).first()
            
            if not app_secret_obj:
                log.warning(f"[{request_id}] 应用不存在 - app_id: {app_id}")
                return ErrorResponse(data="应用不存在")
            
            result = {
                "app_id": app_secret_obj.app_id,
                "app_secret": app_secret_obj.app_secret,
                "status": app_secret_obj.status,
                "create_time": app_secret_obj.create_time.strftime("%Y-%m-%d %H:%M:%S")
            }
            
            log.info(f"[{request_id}] 应用信息查询成功 - app_id: {app_id}, 状态: {app_secret_obj.status}")
            
            return DetailResponse(data=result, msg="获取应用秘钥成功")
            
        except Exception as e:
            log.error(f"[{request_id}] 获取应用秘钥失败: {str(e)}")
            log.error(f"[{request_id}] 异常堆栈: {traceback.format_exc()}")
            return ErrorResponse(data=f"获取应用秘钥失败: {str(e)}")

class AppSecretCreateViews(APIView):
    """
    应用秘钥创建API
    """
    

    
    def post(self, request: Request):
        """
        创建应用秘钥
        POST /api/generate_secret/app/generateSecret
        请求体: {
            "app_id": "应用名称",
            "remark": "备注信息"
        }
        """
        client_ip = get_client_ip(request)
        request_id = f"req_{datetime.now().strftime('%Y%m%d%H%M%S%f')[:-3]}"
        
        log.info(f"[{request_id}] 开始处理创建应用秘钥请求 - IP: {client_ip}, 路径: {request.path}")
        log.info(f"[{request_id}] 请求头信息: {dict(request.headers)}")
        
        try:
            # 记录请求体
            request_body = request.body.decode('utf-8') if request.body else '{}'
            log.info(f"[{request_id}] 请求体: {request_body}")
            
            data = json.loads(request.body) if request.body else {}
            app_id = data.get('app_id')
            remark = data.get('remark', '')
            
            log.info(f"[{request_id}] 解析参数 - app_id: {app_id}, remark: {remark}")
            
            if not app_id:
                log.warning(f"[{request_id}] 参数验证失败: 应用名称不能为空")
                return ErrorResponse(data="app_id不能为空")
            
            # 检查app_id是否已存在
            app_secret_obj = AppSecret.objects.filter(app_id=app_id, is_delete=False).first()
            if app_secret_obj:
                log.info(f"[{request_id}] app_id已存在，直接返回信息 - app_id: {app_id}")
                result = {
                    "app_id": app_secret_obj.app_id,
                    "app_secret": app_secret_obj.app_secret,
                    "app_name": app_secret_obj.app_name,
                    "status": app_secret_obj.status,
                    "create_time": app_secret_obj.create_time.strftime("%Y-%m-%d %H:%M:%S")
                }
                return DetailResponse(data=result, msg="app_id已存在，返回已有信息")
            
            log.info(f"[{request_id}] 参数验证通过，开始生成应用信息")
            
            # 生成app_id和app_secret
            # app_id = AppSecret.generate_app_id()
            app_name = app_id  # 使用app_id作为应用名称
            app_secret = AppSecret.generate_app_secret()
            
            log.info(f"[{request_id}] 生成应用标识 - app_id: {app_id}, app_name: {app_name}, app_secret长度: {len(app_secret)}")
            
            # 创建应用秘钥记录
            app_secret_obj = AppSecret.objects.create(
                app_id=app_id,
                app_secret=app_secret,
                app_name=app_name,
                remark=remark,
                create_by=request.user.username if hasattr(request, 'user') and request.user.is_authenticated else 'system'
            )
            
            result = {
                "app_id": app_secret_obj.app_id,
                "app_secret": app_secret_obj.app_secret,
                "app_name": app_secret_obj.app_name,
                "status": app_secret_obj.status,
                "create_time": app_secret_obj.create_time.strftime("%Y-%m-%d %H:%M:%S")
            }
            
            log.info(f"[{request_id}] 应用秘钥创建成功 - app_id: {app_id}, app_name: {app_name}")
            
            return DetailResponse(data=result, msg="应用秘钥创建成功")
            
        except json.JSONDecodeError as e:
            log.error(f"[{request_id}] JSON解析失败: {str(e)}, 请求体: {request_body}")
            return ErrorResponse(data="请求体格式错误，请使用JSON格式")
        except Exception as e:
            log.error(f"[{request_id}] 创建应用秘钥失败: {str(e)}")
            log.error(f"[{request_id}] 异常堆栈: {traceback.format_exc()}")
            return ErrorResponse(data=f"创建应用秘钥失败: {str(e)}")

class AppSecretManageViews(APIView):
    """
    应用秘钥管理API
    """
    

    
    def get(self, request: Request):
        """
        获取应用秘钥列表
        GET /api/generate_secret/app/secret/list?page=1&size=10&keyword=xxx
        """
        client_ip = get_client_ip(request)
        request_id = f"req_{datetime.now().strftime('%Y%m%d%H%M%S%f')[:-3]}"
        
        log.info(f"[{request_id}] 开始处理获取应用秘钥列表请求 - IP: {client_ip}, 路径: {request.path}")
        log.info(f"[{request_id}] 查询参数: {dict(request.GET)}")
        
        try:
            page = int(request.GET.get('page', 1))
            size = int(request.GET.get('size', 10))
            keyword = request.GET.get('keyword', '')
            
            log.info(f"[{request_id}] 解析参数 - page: {page}, size: {size}, keyword: {keyword}")
            
            # 构建查询条件
            query = Q(is_delete=False)
            if keyword:
                query &= (Q(app_id__icontains=keyword) | Q(app_name__icontains=keyword))
                log.info(f"[{request_id}] 添加关键词过滤条件: {keyword}")
            
            # 查询总数
            total = AppSecret.objects.filter(query).count()
            log.info(f"[{request_id}] 查询到总记录数: {total}")
            
            # 分页查询
            start = (page - 1) * size
            end = start + size
            app_secrets = AppSecret.objects.filter(query).order_by('-create_time')[start:end]
            
            result_list = []
            for app_secret in app_secrets:
                result_list.append({
                    "id": app_secret.id,
                    "app_id": app_secret.app_id,
                    "app_name": app_secret.app_name,
                    "status": app_secret.status,
                    "create_time": app_secret.create_time.strftime("%Y-%m-%d %H:%M:%S"),
                    "update_time": app_secret.update_time.strftime("%Y-%m-%d %H:%M:%S")
                })
            
            result = {
                "list": result_list,
                "total": total,
                "page": page,
                "size": size
            }
            
            log.info(f"[{request_id}] 应用秘钥列表查询成功 - 总数: {total}, 当前页: {page}, 每页大小: {size}")
            
            return DetailResponse(data=result, msg="获取应用秘钥列表成功")
            
        except ValueError as e:
            log.error(f"[{request_id}] 参数类型错误: {str(e)}")
            return ErrorResponse(data="分页参数必须是整数")
        except Exception as e:
            log.error(f"[{request_id}] 获取应用秘钥列表失败: {str(e)}")
            log.error(f"[{request_id}] 异常堆栈: {traceback.format_exc()}")
            return ErrorResponse(data=f"获取应用秘钥列表失败: {str(e)}")
    
    def put(self, request: Request):
        """
        更新应用秘钥状态
        PUT /api/generate_secret/app/secret/update
        请求体: {
            "app_id": "my-app-001",
            "status": true
        }
        """
        client_ip = get_client_ip(request)
        request_id = f"req_{datetime.now().strftime('%Y%m%d%H%M%S%f')[:-3]}"
        
        log.info(f"[{request_id}] 开始处理更新应用秘钥状态请求 - IP: {client_ip}, 路径: {request.path}")
        log.info(f"[{request_id}] 请求头信息: {dict(request.headers)}")
        
        try:
            # 记录请求体
            request_body = request.body.decode('utf-8') if request.body else '{}'
            log.info(f"[{request_id}] 请求体: {request_body}")
            
            data = json.loads(request.body) if request.body else {}
            app_id = data.get('app_id')
            status = data.get('status')
            
            log.info(f"[{request_id}] 解析参数 - app_id: {app_id}, status: {status}")
            
            if not app_id:
                log.warning(f"[{request_id}] 参数验证失败: app_id参数不能为空")
                return ErrorResponse(data="app_id参数不能为空")
            
            if status is None:
                log.warning(f"[{request_id}] 参数验证失败: status参数不能为空")
                return ErrorResponse(data="status参数不能为空")
            
            log.info(f"[{request_id}] 参数验证通过，开始查询应用信息")
            
            # 查询应用
            app_secret_obj = AppSecret.objects.filter(
                app_id=app_id,
                is_delete=False
            ).first()
            
            if not app_secret_obj:
                log.warning(f"[{request_id}] 应用不存在 - app_id: {app_id}")
                return ErrorResponse(data="应用不存在")
            
            # 更新状态
            old_status = app_secret_obj.status
            app_secret_obj.status = status
            app_secret_obj.save()
            
            log.info(f"[{request_id}] 应用状态更新成功 - app_id: {app_id}, 旧状态: {old_status}, 新状态: {status}")
            
            result = {
                "app_id": app_secret_obj.app_id,
                "status": app_secret_obj.status,
                "update_time": app_secret_obj.update_time.strftime("%Y-%m-%d %H:%M:%S")
            }
            
            return DetailResponse(data=result, msg="应用状态更新成功")
            
        except json.JSONDecodeError as e:
            log.error(f"[{request_id}] JSON解析失败: {str(e)}, 请求体: {request_body}")
            return ErrorResponse(data="请求体格式错误，请使用JSON格式")
        except Exception as e:
            log.error(f"[{request_id}] 更新应用状态失败: {str(e)}")
            log.error(f"[{request_id}] 异常堆栈: {traceback.format_exc()}")
            return ErrorResponse(data=f"更新应用状态失败: {str(e)}")
    
    def delete(self, request: Request):
        """
        删除应用秘钥（逻辑删除）
        DELETE /api/generate_secret/app/secret/delete
        请求体: {
            "app_id": "my-app-001"
        }
        """
        client_ip = get_client_ip(request)
        request_id = f"req_{datetime.now().strftime('%Y%m%d%H%M%S%f')[:-3]}"
        
        log.info(f"[{request_id}] 开始处理删除应用秘钥请求 - IP: {client_ip}, 路径: {request.path}")
        log.info(f"[{request_id}] 请求头信息: {dict(request.headers)}")
        
        try:
            # 记录请求体
            request_body = request.body.decode('utf-8') if request.body else '{}'
            log.info(f"[{request_id}] 请求体: {request_body}")
            
            data = json.loads(request.body) if request.body else {}
            app_id = data.get('app_id')
            
            log.info(f"[{request_id}] 解析参数 - app_id: {app_id}")
            
            if not app_id:
                log.warning(f"[{request_id}] 参数验证失败: app_id参数不能为空")
                return ErrorResponse(data="app_id参数不能为空")
            
            log.info(f"[{request_id}] 参数验证通过，开始查询应用信息")
            
            # 查询应用
            app_secret_obj = AppSecret.objects.filter(
                app_id=app_id,
                is_delete=False
            ).first()
            
            if not app_secret_obj:
                log.warning(f"[{request_id}] 应用不存在 - app_id: {app_id}")
                return ErrorResponse(data="应用不存在")
            
            # 逻辑删除
            app_secret_obj.is_delete = True
            app_secret_obj.save()
            
            log.info(f"[{request_id}] 应用删除成功 - app_id: {app_id}")
            
            return DetailResponse(data={"app_id": app_id}, msg="应用删除成功")
            
        except json.JSONDecodeError as e:
            log.error(f"[{request_id}] JSON解析失败: {str(e)}, 请求体: {request_body}")
            return ErrorResponse(data="请求体格式错误，请使用JSON格式")
        except Exception as e:
            log.error(f"[{request_id}] 删除应用失败: {str(e)}")
            log.error(f"[{request_id}] 异常堆栈: {traceback.format_exc()}")
            return ErrorResponse(data=f"删除应用失败: {str(e)}")
